﻿using Autofac;
using Autofac.Extensions.DependencyInjection;
using log4net;
using log4net.Config;
using log4net.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using SSRS.Core;
using SSRS.Util;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using SSRS.Application.Web.Aop;
using SSRS.Util.Codes;

namespace SSRS.PlugIns.Web
{
    public class Startup
    {

        private IServiceProvider RegisterAutofac(IServiceCollection services)
        {
            //业务程序集

           var myBase= AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("SSRS.PlugIns.Base"));
           var myOgran = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("SSRS.PlugIns.Organization"));


           var assembly = this.GetType().GetTypeInfo().Assembly;
             
            var builder = new ContainerBuilder();
            var manager = new ApplicationPartManager();

            manager.ApplicationParts.Add(new AssemblyPart(assembly));
            manager.ApplicationParts.Add(new AssemblyPart(myBase));
            manager.ApplicationParts.Add(new AssemblyPart(myOgran));

            manager.FeatureProviders.Add(new ControllerFeatureProvider());
            manager.FeatureProviders.Add(new SsrsControllerFeatrueProvider());


            var feature = new ControllerFeature();

            manager.PopulateFeature(feature);

            builder.RegisterType<ApplicationPartManager>().AsSelf().SingleInstance();
            builder.RegisterTypes(feature.Controllers.Select(ti => ti.AsType()).ToArray()).PropertiesAutowired();
            builder.Populate(services);



            builder.RegisterType<AopInterceptor>();


            builder.RegisterAssemblyTypes(assembly, myBase, myOgran)
                .Where(type =>
                    typeof(IDependency).IsAssignableFrom(type) && !type.GetTypeInfo().IsAbstract)
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .EnableInterfaceInterceptors().InterceptedBy(typeof(AopInterceptor));


            this.ApplicationContainer = builder.Build();

            return new AutofacServiceProvider(this.ApplicationContainer);
        }
        public static ILoggerRepository LoggerRepository { get; set; }
        public IContainer ApplicationContainer { get; private set; }
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            //log4net

            #region 添加log4net 配置支持

            LoggerRepository = LogManager.CreateRepository("NETCoreRepository");
            //指定配置文件
            dynamic type = (new Program()).GetType();
            string currentDirectory = Path.GetDirectoryName(type.Assembly.Location);
            var fileInfo = new FileInfo(Path.Combine(currentDirectory, "XmlConfig\\log4net.config"));

            #endregion



            #region 添加  session 跨库访问



            #endregion

            XmlConfigurator.Configure(LoggerRepository, fileInfo);
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(
            IServiceCollection services
            )
        {



            services.MyAddHttpContextAccessor();
            services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddControllersAsServices(); ;
            //core的session仅限于controller，想在其他地方使用，还需要进行IHttpContextAccessor注解。
            services.AddSession();
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            return RegisterAutofac(services);

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider svp, IApplicationLifetime applicationLifetime)
        {
            if (env.IsDevelopment())

            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            ////添加系统环境熟悉感
            //config.ApplicationName = env.ApplicationName;
            //config.ContentRootFileProvider = env.ContentRootFileProvider;
            //config.ContentRootPath = env.ContentRootPath;
            //config.EnvironmentName = env.EnvironmentName;
            //config.WebRootFileProvider = env.WebRootFileProvider;
            //config.WebRootPath = env.WebRootPath;
            app.UseSession();
            app.UseStaticHttpContext();

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");

                routes.MapRoute(
                    name: "areas",
                    template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
